﻿@using Fluxor.Blazor.Web.Components;
@using Microsoft.AspNetCore.Html;
@using SimpleIdServer.IdServer.Website.Resources;
@using SimpleIdServer.IdServer.Website.Stores.ClientStore;
@using SimpleIdServer.IdServer.Website.Stores.ScopeStore;
@inherits FluxorComponent
@inject Radzen.DialogService dialogService
@inject NotificationService notificationService
@inject IState<AddScopeState> addScopeState
@inject IDispatcher dispatcher

<RadzenSteps>
    <Steps>
        <RadzenStepsItem Text="@Global.ResourceType">
            <div class="row gy-4">
                @foreach (var scopType in ScopeTypes)
                {
                    <div class="col-md-6">
                        <RadzenCard @onclick="() => SelectResource(scopType)" class="@(SelectedScopeType != null && SelectedScopeType.Name == scopType.Name ? "selected selectable" : "selectable")">
                            <div class="row">
                                <div class="col-md-3">
                                    <RadzenImage Path="@scopType.PictureUrl" Style="width: 60px" />
                                </div>
                                <div class="col">
                                    <h5>@scopType.Name</h5>
                                    <p class="text-muted">@(new MarkupString(scopType.ShortDescription))</p>
                                </div>
                            </div>
                        </RadzenCard>
                    </div>
                }
            </div>

            <hr />

            @if (SelectedScopeType != null)
            {
                <h5><RadzenIcon Icon="info" /> @SelectedScopeType.Name</h5>
                <p class="text-muted">@(new MarkupString(SelectedScopeType.Description))</p>
            }
        </RadzenStepsItem>
        <RadzenStepsItem Text="Create" Disabled="@(SelectedScopeType == null)">
            @if (SelectedScopeType != null)
            {
                switch (SelectedScopeType.Type)
                {
                    // Identity Value
                    case Domains.ScopeTypes.IDENTITY:
                        <RadzenTemplateForm Submit=@AddIdentityResource TItem="IdentityScope" Data=@identityScope>
                            @if (!addScopeState.Value.IsAdding && !string.IsNullOrWhiteSpace(addScopeState.Value.ErrorMessage))
                            {
                                <RadzenAlert AllowClose="false" AlertStyle="AlertStyle.Danger" ShowIcon="true" Variant="Variant.Flat" Shade="Shade.Lighter">@addScopeState.Value.ErrorMessage</RadzenAlert>
                            }
                            <div>
                                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.Name</RadzenText>
                                <RadzenTextBox Name="Name" @bind-Value="@identityScope.Name" Class="w-100"></RadzenTextBox>
                                <RadzenRequiredValidator Component="Name" Text="@Global.NameIsRequired"></RadzenRequiredValidator>
                            </div>
                            <div>
                                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.Description</RadzenText>
                                <RadzenTextArea Name="Description" @bind-Value="@identityScope.Description" Class="w-100"></RadzenTextArea>
                            </div>
                            <div>
                                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.Protocol</RadzenText>
                                <RadzenDropDown Name="Protocol" Class="w-100"
                                    Data=@scopeProtocols
                                    TValue="ScopeProtocols"
                                    @bind-Value=@identityScope.Protocol
                                    TextProperty="Name" ValueProperty="Protocol" />
                                <RadzenRequiredValidator Component="Protocol" Text="@Global.ProtocolIsRequired"></RadzenRequiredValidator>
                            </div>
                            @if (identityScope.Protocol == ScopeProtocols.OPENID)
                            {
                                <div>
                                    <RadzenCheckBox Name="IsExposedInConfigrationEdp" @bind-Value="@identityScope.IsExposedInConfigrationEdp"></RadzenCheckBox>
                                    <RadzenLabel Text="@Global.IsExposed" Component="IsExposedInConfigrationEdp" Style="margin-left: 8px; vertical-align: middle;" />
                                    <p class="text-muted">
                                        @((MarkupString)(Global.IsExposedDescription))
                                    </p>
                                </div>
                            }
                            <RadzenButton class="mt-1" Variant="Variant.Flat" ButtonType="ButtonType.Submit" ButtonStyle="ButtonStyle.Success" Text="@(addScopeState.Value.IsAdding ? @Global.Adding : Global.Save)" Disabled="@(addScopeState.Value.IsAdding)" />
                        </RadzenTemplateForm>
                        break;
                    // API RESOURCE 
                    case Domains.ScopeTypes.APIRESOURCE:
                        <RadzenTemplateForm Submit=@AddApiResource TItem="ApiScope" Data=@apiScope>
                            @if (!addScopeState.Value.IsAdding && !string.IsNullOrWhiteSpace(addScopeState.Value.ErrorMessage))
                            {
                                <RadzenAlert AllowClose="false" AlertStyle="AlertStyle.Danger" ShowIcon="true" Variant="Variant.Flat" Shade="Shade.Lighter">@addScopeState.Value.ErrorMessage</RadzenAlert>
                            }
                            <div>
                                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.Name</RadzenText>
                                <RadzenTextBox Name="Name" @bind-Value="@apiScope.Name" Class="w-100"></RadzenTextBox>
                                <RadzenRequiredValidator Component="Name" Text="@Global.NameIsRequired"></RadzenRequiredValidator>
                            </div>
                            <div>
                                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@Global.Description</RadzenText>
                                <RadzenTextArea Name="Description" @bind-Value="@apiScope.Description" Class="w-100"></RadzenTextArea>
                            </div>
                            <div>
                                <RadzenCheckBox Name="IsExposedInConfigrationEdp" @bind-Value="@apiScope.IsExposedInConfigrationEdp"></RadzenCheckBox>
                                <RadzenLabel Text="@Global.IsExposed" Component="IsExposedInConfigrationEdp" Style="margin-left: 8px; vertical-align: middle;" />
                                <p class="text-muted">
                                    @((MarkupString)(Global.IsExposedDescription))
                                </p>
                            </div>
                            <RadzenButton class="mt-1" Variant="Variant.Flat" ButtonType="ButtonType.Submit" ButtonStyle="ButtonStyle.Success" Text="@(addScopeState.Value.IsAdding ? Global.Adding : Global.Save)" Disabled="@(addScopeState.Value.IsAdding)" />
                        </RadzenTemplateForm>
                        break;
                }
            }
        </RadzenStepsItem>
    </Steps>
</RadzenSteps>

@code {
    record ScopeType
    {
        public string Name { get; set; } = null!;
        public string ShortDescription { get; set; } = null!;
        public string Description { get; set; } = null!;
        public ScopeTypes Type { get; set; }
        public string PictureUrl { get; set; } = null!;
    }

    record IdentityScope
    {
        public string Name { get; set; } = null!;
        public string Description { get; set; } = null!;
        public bool IsExposedInConfigrationEdp { get; set; } = false;
        public ScopeProtocols Protocol { get; set; } = ScopeProtocols.OPENID;
    }

    record ApiScope
    {
        public string Name { get; set; } = null!;
        public string Description { get; set; } = null!;
        public bool IsExposedInConfigrationEdp { get; set; } = false;
    }

    record IdentityScopeProtocolInfo
    {
        public string Name { get; set; }
        public ScopeProtocols Protocol { get; set; }
    }

    List<IdentityScopeProtocolInfo> scopeProtocols = new List<IdentityScopeProtocolInfo>
        {
            new IdentityScopeProtocolInfo { Protocol = ScopeProtocols.OPENID, Name = "OPENID" },
            new IdentityScopeProtocolInfo { Protocol = ScopeProtocols.SAML, Name = "SAML" }
        };

    IdentityScope identityScope = new IdentityScope();
    ApiScope apiScope = new ApiScope();

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        SubscribeToAction<AddScopeSuccessAction>((act) =>
        {
            dialogService.Close();
            notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = string.Format(Global.ScopeAdded, act.Name) });
            StateHasChanged();
        });
        dispatcher.Dispatch(new StartAddScopeAction());
    }

    ICollection<ScopeType> ScopeTypes { get; set; } = new List<ScopeType>
    {
        new ScopeType { Name = Global.IdentityValue, ShortDescription = Global.AccessClaimsAuthenticatedUser, Description = Global.ClientsAuthorizedToAccessSpecificClaims, Type = Domains.ScopeTypes.IDENTITY, PictureUrl = "_content/SimpleIdServer.IdServer.Website/images/IdentityResource.png" },
        new ScopeType { Name = Global.APIValue, ShortDescription = Global.AccessOneOrMoreApiResources, Description = Global.ClientsAuthorizedToAccessApiResource, Type = Domains.ScopeTypes.APIRESOURCE, PictureUrl = "_content/SimpleIdServer.IdServer.Website/images/ApiResource.png" }
    };

    ScopeType? SelectedScopeType { get; set; } = null;

    void SelectResource(ScopeType resourceType)
    {
        SelectedScopeType = resourceType;
    }

    void AddIdentityResource(IdentityScope identityResource)
    {
        dispatcher.Dispatch(new AddIdentityScopeAction { Name = identityResource.Name, Description = identityResource.Description, IsExposedInConfigurationEdp = identityResource.IsExposedInConfigrationEdp, Protocol = identityResource.Protocol });
    }

    void AddApiResource(ApiScope apiResource)
    {
        dispatcher.Dispatch(new AddApiScopeAction { Name = apiResource.Name, Description = apiResource.Description, IsExposedInConfigurationEdp = apiResource.IsExposedInConfigrationEdp });
    }
}